/**
 *  \file can_ext_tx.c
 *
 *  \brief External can transmit function
 *
 *  \author dajin.li  <dajin.li@linde-china.com>
 *
 *
 */

/*===============================================[ private includes  ]================================================*/
#include "can_ext_tx.h"
#include "../pal/pal_mem.h"
#include "../sched/sched.h"
#include "../canmsg/canmsg.h"
#include "../nth/nth.h"
#include "../can/can.h"
#include "../endian/endian_write.h"
#include "../endian/endian.h"
#include "../canid/canid.h"
#include "../cancom/cancom.h"
#include "../saturated/saturated.h"
#include "../kwpservices/kwpservices.h"
#include "../timerecorder/timerecorder.h"
#include "../mlib/middle.h"
#include "../specs/specs.h"
#include "../control_traction/traction.h"
#include "../steer/steer.h"
#include <math.h>
#include "../app/app.h"
#include "../supervisor/supervisor.h"
#include "../cfg/service_cfg.h"
#include "../bdi/bdi.h"

#include "can_ext_tx.h"


/*===============================================[ private defines   ]================================================*/
/*Vehicle debug 0 0x620*/
#define Vechicle_debug0_0_u16   can_ext_tx.signal.debugv_tx_pdo0.store.debugv_dbg0_0
#define Vechicle_debug0_1_u16   can_ext_tx.signal.debugv_tx_pdo0.store.debugv_dbg0_1
#define Vechicle_debug0_2_u16   can_ext_tx.signal.debugv_tx_pdo0.store.debugv_dbg0_2
#define Vechicle_debug0_3_u16   can_ext_tx.signal.debugv_tx_pdo0.store.debugv_dbg0_3

/*Vehicle debug 1 0x621*/
#define Vechicle_debug1_0_u16   can_ext_tx.signal.debugv_tx_pdo1.store.debugv_dbg1_0
#define Vechicle_debug1_1_u16   can_ext_tx.signal.debugv_tx_pdo1.store.debugv_dbg1_1
#define Vechicle_debug1_2_u16   can_ext_tx.signal.debugv_tx_pdo1.store.debugv_dbg1_2
#define Vechicle_debug1_3_u16   can_ext_tx.signal.debugv_tx_pdo1.store.debugv_dbg1_3

/*Vehicle debug 2 0x622*/
#define Vechicle_debug2_0_u16   can_ext_tx.signal.debugv_tx_pdo2.store.debugv_dbg2_0
#define Vechicle_debug2_1_u16   can_ext_tx.signal.debugv_tx_pdo2.store.debugv_dbg2_1
#define Vechicle_debug2_2_u16   can_ext_tx.signal.debugv_tx_pdo2.store.debugv_dbg2_2
#define Vechicle_debug2_3_u16   can_ext_tx.signal.debugv_tx_pdo2.store.debugv_dbg2_3

/*Vehicle debug 3 0x623*/
#define Vechicle_debug3_0_u16   can_ext_tx.signal.debugv_tx_pdo3.store.debugv_dbg3_0
#define Vechicle_debug3_1_u16   can_ext_tx.signal.debugv_tx_pdo3.store.debugv_dbg3_1
#define Vechicle_debug3_2_u16   can_ext_tx.signal.debugv_tx_pdo3.store.debugv_dbg3_2
#define Vechicle_debug3_3_u16   can_ext_tx.signal.debugv_tx_pdo3.store.debugv_dbg3_3

/*Vehicle debug 4 0x624*/
#define Vechicle_debug4_0_u16   can_ext_tx.signal.debugv_tx_pdo4.store.debugv_dbg4_0
#define Vechicle_debug4_1_u16   can_ext_tx.signal.debugv_tx_pdo4.store.debugv_dbg4_1
#define Vechicle_debug4_2_u16   can_ext_tx.signal.debugv_tx_pdo4.store.debugv_dbg4_2
#define Vechicle_debug4_3_u16   can_ext_tx.signal.debugv_tx_pdo4.store.debugv_dbg4_3


/*Vehicle Trac PDOF 0x81*/
#define T_EnableF_Lft_b2        can_ext_tx.signal.v_trac_tx_pdof.store.t_enablef_lft
#define T_EnableF_Rgh_b2        can_ext_tx.signal.v_trac_tx_pdof.store.t_enablef_rgh
#define T_MessCountF_b4         can_ext_tx.signal.v_trac_tx_pdof.store.t_msg_countF
#define T_PwmEnableF_lft_b1     can_ext_tx.signal.v_trac_tx_pdof.store.t_pwmenablef_lft
#define T_PwmEnableF_rgh_b1     can_ext_tx.signal.v_trac_tx_pdof.store.t_pwmenablef_rgh
#define T_TorqueSetF_lft_s16    can_ext_tx.signal.v_trac_tx_pdof.store.t_torquesetf_lft
#define T_TorqueSetF_rgh_s16    can_ext_tx.signal.v_trac_tx_pdof.store.t_torquesetf_rgh
#define T_Discharge_lft_b1      can_ext_tx.signal.v_trac_tx_pdof.store.t_Discharge_lft
#define T_Discharge_rgh_b1      can_ext_tx.signal.v_trac_tx_pdof.store.t_Discharge_rgh


#define TF_dm2_b1               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm2
#define TF_dm3_b1               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm3
#define TF_dm4_b1               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm4
#define TF_dm5_b1               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm5

#define TF_dm7_u8               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm7
#define TF_dm8_u8               can_ext_tx.signal.v_trac_tx_pdof.store.t_tf_dm8

/*Vehicle Trac PDO4 0x481*/

#define TruckWorkTime_u32       can_ext_tx.signal.v_trac_tx_pdo4.store.v_truckworktime

/*Vehicle lift PDO1 0x182*/

#define L2_dm2_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm2 
#define L2_dm3_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm3
#define L2_dm4_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm4
#define L2_dm5_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm5
#define L2_dm6_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm6
#define L2_dm7_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm7
#define L2_dm8_b1               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm8
#define L2_dm9_u8               can_ext_tx.signal.v_lift_tx_pdo1.store.l2_dm9
#define L_CMain_b1              can_ext_tx.signal.v_lift_tx_pdo1.store.l_cont_main
#define L_Enable_b2             can_ext_tx.signal.v_lift_tx_pdo1.store.l_enable
#define L_MessCount_b4          can_ext_tx.signal.v_lift_tx_pdo1.store.l2_msg_count
#define L_MTemp_s8              can_ext_tx.signal.v_lift_tx_pdo1.store.l_motor_temp
#define L_PwmEnable_b1          can_ext_tx.signal.v_lift_tx_pdo1.store.l_pwm_enable
#define L_SpeedSet_s16          can_ext_tx.signal.v_lift_tx_pdo1.store.l_speedset
#define L_TorqueSet_s16         can_ext_tx.signal.v_lift_tx_pdo1.store.l_torqueset
#define L_Discharge_b1          can_ext_tx.signal.v_lift_tx_pdo1.store.l_discharge

/*Vehicle lift PDO2 0x282*/
#define ChlState_b1             can_ext_tx.signal.v_lift_tx_pdo2.store.lift_ChlState
#define IndHeight_b1            can_ext_tx.signal.v_lift_tx_pdo2.store.lift_ind_height
#define L1_MotorTemp_s8         can_ext_tx.signal.v_lift_tx_pdo2.store.lift_mot_temp
#define Lh2State_b1             can_ext_tx.signal.v_lift_tx_pdo2.store.lift_lh12_state
#define LhpDir_b2               can_ext_tx.signal.v_lift_tx_pdo2.store.lift_lph_dir
#define LhpState_b2             can_ext_tx.signal.v_lift_tx_pdo2.store.lift_lph_state
#define Lift2MsgCnt_b2          can_ext_tx.signal.v_lift_tx_pdo2.store.lift2_msg_cnt
#define LiftActive_b1           can_ext_tx.signal.v_lift_tx_pdo2.store.lift_active
#define LiftCtrlErrState_b1     can_ext_tx.signal.v_lift_tx_pdo2.store.lift_ctrl_err_state
#define LiftFuncBuzzCmd_b1      can_ext_tx.signal.v_lift_tx_pdo2.store.lift_func_buzz_cmd
#define LiftH11Cmd_b1           can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h11_cmd
#define LiftH14Cmd_b1           can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h14_cmd
#define LiftH17Cmd_b1           can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h17_cmd
#define LiftH3Cmd_b1            can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h3_cmd
#define LiftH5Cmd_b1            can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h5_cmd
#define LiftH7Cmd_b1            can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h7_cmd
#define LiftH8Cmd_b1            can_ext_tx.signal.v_lift_tx_pdo2.store.lift_h8_cmd
#define LiftHeight_b15          can_ext_tx.signal.v_lift_tx_pdo2.store.lift_height
#define LiftLoadState_b1        can_ext_tx.signal.v_lift_tx_pdo2.store.lift_load_state
#define LiftMastPos_b1          can_ext_tx.signal.v_lift_tx_pdo2.store.lift_mast_pos
#define LiftSymbACmd_b1         can_ext_tx.signal.v_lift_tx_pdo2.store.lift_symb_a_cmd
#define LiftTiltAng_s8          can_ext_tx.signal.v_lift_tx_pdo2.store.lift_tilt_ang
#define LiftWarnBuzzCmd_b1      can_ext_tx.signal.v_lift_tx_pdo2.store.lift_warn_buzz_cmd
#define LloState_b2             can_ext_tx.signal.v_lift_tx_pdo2.store.lift_llo_state
#define TapDir_b2               can_ext_tx.signal.v_lift_tx_pdo2.store.lift_tap_dir
#define TapState_b2             can_ext_tx.signal.v_lift_tx_pdo2.store.lift_tap_state
#define WeightProc_b1           can_ext_tx.signal.v_lift_tx_pdo2.store.lift_weight_proc


/*Vehicle  PDO1 0x181*/
#define TrSpeed_s16             can_ext_tx.signal.v_trac_tx_pdo1.store.v_tr_speed
#define Truck_ForceN_s16        can_ext_tx.signal.v_trac_tx_pdo1.store.v_truckforce_n
#define TruckSpeed_s16          can_ext_tx.signal.v_trac_tx_pdo1.store.v_truckspeed
#define TSteerAngle_s16         can_ext_tx.signal.v_trac_tx_pdo1.store.v_tsteerangle

/*Vehicle  PDO2 0x281*/
#define BatCharState_u8         can_ext_tx.signal.v_trac_tx_pdo2.store.v_BrakeCharState
#define BrakeState_b1           can_ext_tx.signal.v_trac_tx_pdo2.store.v_BrakeState
#define HourmeterCmd_b1         can_ext_tx.signal.v_trac_tx_pdo2.store.v_HourmeterCmd
#define IndBackw_b1             can_ext_tx.signal.v_trac_tx_pdo2.store.v_IndBackw
#define IndForw_b1              can_ext_tx.signal.v_trac_tx_pdo2.store.v_IndForw
#define T_BatCurr_u16           can_ext_tx.signal.v_trac_tx_pdo2.store.v_BatCurrent
#define T_BatVolt_u16           can_ext_tx.signal.v_trac_tx_pdo2.store.v_BatVolt
#define T_MotTemp_lft_u8        can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracMotorTemp_lft
#define T_Seat_b1               can_ext_tx.signal.v_trac_tx_pdo2.store.v_T_seat
#define T_TotalDischarge_b1     can_ext_tx.signal.v_trac_tx_pdo2.store.v_T_TotalDischarge
#define TracActive_b1           can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracActive
#define TracCtrlErrState_b1     can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracCtrlErrState
#define TracH11Cmd_b1           can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH11Cmd
#define TracH3Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH3Cmd
#define TracH5Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH5Cmd
#define TracH7Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH7Cmd
#define TracH8Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH8Cmd
#define TracH9Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracH9Cmd
#define TracSymbACmd_b1         can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracSymbACmd
#define TracWarnBuzzCmd_b1      can_ext_tx.signal.v_trac_tx_pdo2.store.v_tracWarnBuzzCmd

/*Vehicle  PDO3 0x381*/
#define Vehicle_DTC1_u16        can_ext_tx.signal.v_trac_tx_pdo3.store.v_dtc1
#define Vehicle_DTC2_u16        can_ext_tx.signal.v_trac_tx_pdo3.store.v_dtc2
#define Vehicle_DTC3_u16        can_ext_tx.signal.v_trac_tx_pdo3.store.v_dtc3
#define Vehicle_DTC4_u16        can_ext_tx.signal.v_trac_tx_pdo3.store.v_dtc4

/*Vehicle  PDO5 0x304*/
#define PbBrake_b1              can_ext_tx.signal.v_trac_tx_pdo5.store.v_PBrake
#define PermHeight_u16          can_ext_tx.signal.v_trac_tx_pdo5.store.v_PermHeight
#define PermTiltAngB_u8         can_ext_tx.signal.v_trac_tx_pdo5.store.v_PermTiltAngB
#define PermTiltAngF_u8         can_ext_tx.signal.v_trac_tx_pdo5.store.v_PermTiltAngF
#define RemWorkTime_b11         can_ext_tx.signal.v_trac_tx_pdo5.store.v_RemWorkTime
#define RWT_Ovfl_b1_b1          can_ext_tx.signal.v_trac_tx_pdo5.store.v_RWTOvfl
#define SpLimState_b1           can_ext_tx.signal.v_trac_tx_pdo5.store.v_SpLimState
#define TLift_b1                can_ext_tx.signal.v_trac_tx_pdo5.store.v_Tlife
#define Trac5MsgCnt_b4          can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracMsgCnt
#define TracDirLev_b2           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracDirLev
#define TracFuncBuzzCmd_b1      can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracFuncBuzzCmd
#define TracH14Cmd_b1           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH14Cmd
#define TracH15Cmd_b1           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH15Cmd
#define TracH16Cmd_b1           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH16Cmd
#define TracH17Cmd_b1           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH17Cmd
#define TracH2Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH2Cmd
#define TracH4Cmd_b1            can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracH4Cmd
#define TracInterv_b2           can_ext_tx.signal.v_trac_tx_pdo5.store.v_TracInterV
#define TrBrk_b1                can_ext_tx.signal.v_trac_tx_pdo5.store.v_TrBrk

#define VSET_NEUTRAL            2


/*===============================================[ private datatypes ]================================================*/
struct can_ext_tx_signal
{
    union
    {
        U8  u8data;
        struct
        {
            U8 debugv_enable_dbg0:1;               /*Byte0 0  :0*/
            U8 debugv_enable_dbg1:1;               /*Byte0 1  :1*/
            U8 debugv_enable_dbg2:1;               /*Byte0 2  :2*/
            U8 debugv_enable_dbg3:1;               /*Byte0 3  :3*/
            U8 debugv_enable_dbg4:1;               /*Byte0 4  :4*/
        }store;
    }debugv_tx_enable;

    union
    {
        U8  u8data[8];
        struct
        {
            U16 debugv_dbg0_0;               /*Byte0:1 0  :15*/
            U16 debugv_dbg0_1;               /*Byte2:3 16 :31*/
            U16 debugv_dbg0_2;               /*Byte4:5 32 :47*/
            U16 debugv_dbg0_3;               /*Byte4:5 48 :63*/
        }store;
    }debugv_tx_pdo0;
    union
    {
        U8  u8data[8];
        struct
        {
            U16 debugv_dbg1_0;               /*Byte0:1 0  :15*/
            U16 debugv_dbg1_1;               /*Byte2:3 16 :31*/
            U16 debugv_dbg1_2;               /*Byte4:5 32 :47*/
            U16 debugv_dbg1_3;               /*Byte4:5 48 :63*/
        }store;
    }debugv_tx_pdo1;

    union
    {
        U8  u8data[8];
        struct
        {
            U16 debugv_dbg2_0;               /*Byte0:1 0  :15*/
            U16 debugv_dbg2_1;               /*Byte2:3 16 :31*/
            U16 debugv_dbg2_2;               /*Byte4:5 32 :47*/
            U16 debugv_dbg2_3;               /*Byte4:5 48 :63*/
        }store;
    }debugv_tx_pdo2;

    union
    {
        U8  u8data[8];
        struct
        {
            U16 debugv_dbg3_0;               /*Byte0:1 0  :15*/
            U16 debugv_dbg3_1;               /*Byte2:3 16 :31*/
            U16 debugv_dbg3_2;               /*Byte4:5 32 :47*/
            U16 debugv_dbg3_3;               /*Byte4:5 48 :63*/
        }store;
    }debugv_tx_pdo3;

    union
    {
        U8  u8data[8];
        struct
        {
            U16 debugv_dbg4_0;               /*Byte0:1 0  :15*/
            U16 debugv_dbg4_1;               /*Byte2:3 16 :31*/
            U16 debugv_dbg4_2;               /*Byte4:5 32 :47*/
            U16 debugv_dbg4_3;               /*Byte4:5 48 :63*/
        }store;
    }debugv_tx_pdo4;


    union
    {
        U8  u8data[8];
        struct
        {
            S16 l_torqueset;                 /*Byte0:1 0  :15*/
            S16 l_speedset;                  /*Byte2:3 16 :31*/
            U8  l2_dm9;                      /*Byte4   32 :39*/
            S8  l_motor_temp;                /*Byte5   40 :47*/
            U8  l_enable:2;                  /*Byte6   48 :49*/
            U8  l_cont_main:1;               /*Byte6   50 :50*/
            U8  l_pwm_enable:1;              /*Byte6   51 :51*/
            U8  l_discharge:1;               /*Byte6   52 :52*/
            U8  l2_dm2:1;                    /*Byte6   53 :53*/
            U8  l2_dm3:1;                    /*Byte6   54 :54*/
            U8  l2_dm4:1;                    /*Byte6   55 :55*/
            U8  l2_dm5:1;                    /*Byte7   56 :56*/
            U8  l2_dm6:1;                    /*Byte7   57 :57*/
            U8  l2_dm7:1;                    /*Byte7   58 :58*/
            U8  l2_dm8:1;                    /*Byte7   59 :59*/
            U8  l2_msg_count:4;              /*Byte7   60 :63*/
        }store;
    }v_lift_tx_pdo1;

    union
    {
        U8  u8data[8];
        struct
        {
            U8  lift_warn_buzz_cmd:1;               /*Byte0   0  :0*/
            U8  lift_symb_a_cmd:1;                  /*Byte0   1  :1*/
            U8  lift_ctrl_err_state:1;              /*Byte0   2  :2*/
            U8  lift_h7_cmd:1;                      /*Byte0   3  :3*/
            U8  lift_h11_cmd:1;                     /*Byte0   4  :4*/
            U8  lift_h3_cmd:1;                      /*Byte0   5  :5*/
            U8  lift_h17_cmd:1;                     /*Byte0   6  :6*/
            U8  lift_lh12_state:1;                  /*Byte0   7  :7*/
            U8  lift_h8_cmd:1;                      /*Byte1   8  :8*/
            U8  lift_h5_cmd:1;                      /*Byte1   9  :9*/
            U8  lift_ind_height:1;                  /*Byte1   10 :10*/
            U8  lift_h14_cmd:1;                     /*Byte1   11 :11*/
            U8  lift_load_state:1;                  /*Byte1   12 :12*/
            U8  lift_mast_pos:1;                    /*Byte1   13 :13*/
            U8  lift_weight_proc:1;                 /*Byte1   14 :14*/
            U8  lift_active:1;                      /*Byte1   15 :15*/
            S8  lift_mot_temp:8;                    /*Byte2   16 :23*/
            U8  lift_lph_dir:2;                     /*Byte3   24 :25*/
            U8  lift_tap_dir:2;                     /*Byte3   26 :27*/
            U8  lift2_msg_cnt:4;                    /*Byte3   28 :31*/
            S16 lift_height:15;                     /*Byte4:5 32 :46*/
            U8  lift_ChlState:1;                    /*Byte5   47 :47*/
            S8  lift_tilt_ang;                      /*Byte6   48 :55*/
            U8  lift_lph_state:2;                   /*Byte7   56 :57*/
            U8  lift_tap_state:2;                   /*Byte7   58 :59*/
            U8  lift_llo_state:2;                   /*Byte7   60 :61*/
            U8  lift_func_buzz_cmd:1;               /*Byte7   62 :62*/
        }store;
    }v_lift_tx_pdo2;

    union
    {
        U8  u8data[8];
        struct
        {
            U16 v_dtc1;               /*Byte0:1 0  :15*/
            U16 v_dtc2;               /*Byte2:3 16 :31*/
            U16 v_dtc3;               /*Byte4:5 32 :47*/
            U16 v_dtc4;               /*Byte4:5 48 :63*/
        }store;
    }v_trac_tx_pdo3;

    union
    {
        U8  u8data[8];
        struct
        {
            S16 t_torquesetf_lft;                   /*Byte0:1  0  :15  unit nm, scale 0.1*/
            U8  t_enablef_lft:2;                    /*Byte2    16 :17*/
            U8  t_pwmenablef_lft:1;                 /*Byte2    18 :18*/
            U8  t_Discharge_lft:1;                  /*Byte2    19 :19*/
            U8  t_tf_dm2:1;                         /*Byte2    20 :20*/
            U8  t_tf_dm3:1;                         /*Byte2    21 :21*/
            U8  t_tf_dm4:1;                         /*Byte2    22 :22*/
            U8  t_tf_dm5:1;                         /*Byte2    23 :23*/
            U8  t_tf_dm8;                           /*Byte3    24 :31*/
            S16 t_torquesetf_rgh;                   /*Byte4:5  32 :47 unit nm, scale 0.1*/
            U8  t_enablef_rgh:2;                    /*Byte6    48 :49*/
            U8  t_pwmenablef_rgh:1;                 /*Byte6    50 :50*/
            U8  t_Discharge_rgh:1;                  /*Byte6    51 :51*/
            U8  t_msg_countF:4;                     /*Byte6    52 :55*/
            U8  t_tf_dm7;                           /*Byte7    56 :63*/
        }store;
    }v_trac_tx_pdof;



    union
    {
        U8  u8data[8];
        struct
        {
            U32 v_truckworktime;      /*Byte0:3 0  :31*/
        }store;
    }v_trac_tx_pdo4;




    union
    {
        U8  u8data[8];
        struct
        {
            S16 v_tr_speed;               /*Byte0:1 0  :15*  unit mm/s*/
            S16 v_truckforce_n;           /*Byte2:3 16 :31   unit N*/
            S16 v_truckspeed;             /*Byte4:5 32 :47   unit km/h, sacle 0.001*/
            S16 v_tsteerangle;            /*Byte4:5 48 :63   unit deg, scale 0.1*/
        }store;
    }v_trac_tx_pdo1;

    union
    {
        U8  u8data[8];
        struct
        {
            U8  v_tracWarnBuzzCmd:1;        /*Byte0   0  : 0*/
            U8  v_tracSymbACmd:1;           /*Byte0   1  : 1*/
            U8  v_tracCtrlErrState:1;       /*Byte0   2  : 2*/
            U8  v_tracH7Cmd:1;              /*Byte0   3  : 3*/
            U8  v_tracH11Cmd:1;             /*Byte0   4  : 4*/
            U8  v_tracH3Cmd:1;              /*Byte0   5  : 5*/
            U8  v_T_seat:1;                 /*Byte0   6  : 6*/
            U8  v_T_TotalDischarge:1;       /*Byte0   7  : 7*/
            U8  v_tracH8Cmd:1;              /*Byte1   8  : 8*/
            U8  v_tracH5Cmd:1;              /*Byte1   9  : 9*/
            U8  v_HourmeterCmd:1;           /*Byte1   10 : 10*/
            U8  v_BrakeState:1;             /*Byte1   11 : 11*/
            U8  v_IndForw:1;                /*Byte1   12 : 12*/
            U8  v_IndBackw:1;               /*Byte1   13 : 13*/
            U8  v_tracH9Cmd:1;              /*Byte1   14 : 14*/
            U8  v_tracActive:1;             /*Byte1   15 : 15*/
            U8  v_tracMotorTemp_lft;        /*Byte2   16 : 23*/
            U8  v_BrakeCharState;           /*Byte3   24 : 31*/
            U16 v_BatVolt;                  /*Byte4:5 32 : 47*/
            U16 v_BatCurrent;               /*Byte6:7 48 : 63*/
        }store;
    }v_trac_tx_pdo2;



    union
    {
        U8  u8data[8];
        struct
        {
            U16 v_RemWorkTime:11;                /*Byte0:1  0  :10*/
            U16 v_RWTOvfl:1;                     /*Byte1    11 :11*/
            U8  v_PBrake:1;                      /*Byte1    12 :12*/
            U8  v_TracFuncBuzzCmd:1;             /*Byte1    13 :13*/
            U8  v_TracH15Cmd:1;                  /*Byte1    14 :14*/
            U8  v_TracH16Cmd:1;                  /*Byte1    15 :15*/
            U8  v_PermTiltAngF:7;                /*Byte2    16 :22*/
            U8  v_TrBrk:1;                       /*Byte2    23 :23*/
            U8  v_PermTiltAngB:7;                /*Byte2    24 :30*/
            U8  v_SpLimState:1;                  /*Byte2    31 :31*/
            U16 v_PermHeight:15;                 /*Byte3:4  32 :46*/
            U8  v_Tlife:1;                       /*Byte5    47 :47*/
            U8  v_TracInterV:2;                  /*Byte6    48 :49*/
            U8  v_reservebit:4;                  /*Byte6    50 :53*/
            U8  v_TracH2Cmd:1;                   /*Byte6    54 :54*/
            U8  v_TracH4Cmd:1;                   /*Byte6    55 :55*/
            U8  v_TracH14Cmd:1;                  /*Byte7    56 :56*/
            U8  v_TracH17Cmd:1;                  /*Byte7    57 :57*/
            U8  v_TracDirLev:2;                  /*Byte7    58 :59*/
            U8  v_TracMsgCnt:4;                  /*Byte7    60 :63*/
        }store;
    }v_trac_tx_pdo5;
};

/** Private variables */
struct can_ext_tx_private
{
   struct tasklet task_100ms;
   struct tasklet task_10ms;
   struct tasklet task_1ms;
   U16 delay_cnt_2ms  ;
   U16 delay_cnt_10ms ;
   U16 delay_cnt_20ms ;
   U16 delay_cnt_40ms ;
   U16 delay_cnt_50ms ;
   U16 delay_cnt_1000ms;

   struct can_ext_tx_signal signal;

};


/*===============================================[ private variables ]================================================*/
static struct can_ext_tx_private can_ext_tx;
static U8 DTCcnt;

/*===============================================[ private functions ]================================================*/
static void can_ext_tx_100ms_service (struct tasklet *task);
static void can_ext_tx_10ms_service (struct tasklet *task);
static void can_ext_tx_1ms_service (struct tasklet *task);
static void can_ext_tx_send_msg_100ms(void);

static void can_ext_tx_send_msg_10ms(void);
static void can_ext_tx_send_msg_1ms(void);

static void PrTrmExtLiftPDO1(void);
static void PrTrmExtLiftPDO2(void);

static void PrTrmExtTracPDOF(void);

static void PrTrmExtTracPDO1(void);
static void PrTrmExtTracPDO2(void);
static void PrTrmExtTracPDO3(void);
static void PrTrmExtTracPDO4(void);
static void PrTrmExtTracPDO5(void);

static void PrTrmExtDebugPDO0(void);
static void PrTrmExtDebugPDO1(void);
static void PrTrmExtDebugPDO2(void);
static void PrTrmExtDebugPDO3(void);
static void PrTrmExtDebugPDO4(void);



/*================================================[ inline functions ]================================================*/

/*================================================[ public functions ]================================================*/
RC can_ext_tx_initialize( void )
{
   pal_memzero( &can_ext_tx, sizeof can_ext_tx);

   can_ext_tx.delay_cnt_10ms = 1;
   can_ext_tx.delay_cnt_20ms = 3;
   can_ext_tx.delay_cnt_40ms = 5;

   can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg0 = 1;
   can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg1 = 1;
   can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg2 = 1;
   can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg3 = 1;
   can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg4 = 1;
   
   tasklet_assign( sched_get_slice_100ms(), &can_ext_tx.task_100ms,  can_ext_tx_100ms_service, NIL );
   tasklet_assign( sched_get_slice_10ms(),  &can_ext_tx.task_10ms,   can_ext_tx_10ms_service,  NIL );
   tasklet_assign( sched_get_slice_1ms(),   &can_ext_tx.task_1ms,    can_ext_tx_1ms_service,   NIL );

   return RC_SUCCESS;
}


/*===============================================[ private functions ]================================================*/

static void can_ext_tx_100ms_service (struct tasklet *task)
{
   UNREFERENCED( task );
   
   can_ext_tx_send_msg_100ms();
}

static void can_ext_tx_10ms_service (struct tasklet *task)
{
   UNREFERENCED( task );

   can_ext_tx_send_msg_10ms();

}
static void can_ext_tx_1ms_service (struct tasklet *task)
{
    UNREFERENCED( task );
    can_ext_tx_send_msg_1ms();
}

static void can_ext_tx_send_msg_100ms(void)
{
    if(kwpservices_get_passive_mode())
    {
        /* send no process data when switched to passive mode */
    }
    else
    {
        PrTrmExtTracPDO3(); /*40ms*/
        can_tx( can_channel_ext, V_PDO3_TX,     can_ext_tx.signal.v_trac_tx_pdo3.u8data,8);//can_ext_tx_send_v_pdo3();
        if( NTH( &can_ext_tx.delay_cnt_1000ms, 9 ))
        {
            PrTrmExtTracPDO4(); /*1000ms*/ 
            can_tx( can_channel_ext, V_Trac_PDO4_TX, can_ext_tx.signal.v_trac_tx_pdo4.u8data,8);//can_ext_tx_send_trac_pdo4();
        }
    }
}

static void can_ext_tx_send_msg_10ms(void)
{
    if(kwpservices_get_passive_mode())
    {
      /* send no process data when switched to passive mode */
    }
    else
    {
        if( NTH( &can_ext_tx.delay_cnt_50ms, 4) )
        {
            PrTrmExtDebugPDO0();/*50ms*/
            PrTrmExtDebugPDO1();/*50ms*/
            PrTrmExtDebugPDO2();/*50ms*/
            PrTrmExtDebugPDO3();/*50ms*/
            PrTrmExtDebugPDO4();/*50ms*/
            if(can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg0)
            {
                can_tx( can_channel_ext, DebugV_PDO0_Tx,can_ext_tx.signal.debugv_tx_pdo0.u8data,8);//can_ext_tx_send_v_debug0();
            }
            if(can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg1)
            {
                can_tx( can_channel_ext, DebugV_PDO1_Tx,can_ext_tx.signal.debugv_tx_pdo1.u8data,8);//can_ext_tx_send_v_debug1();
            }
            if(can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg2)
            {
                can_tx( can_channel_ext, DebugV_PDO2_Tx,can_ext_tx.signal.debugv_tx_pdo2.u8data,8);//can_ext_tx_send_v_debug2();
            }

            if(can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg3)
            {
                can_tx( can_channel_ext, DebugV_PDO3_Tx,can_ext_tx.signal.debugv_tx_pdo3.u8data,8);//can_ext_tx_send_v_debug3();
            }
            if(can_ext_tx.signal.debugv_tx_enable.store.debugv_enable_dbg4)
            {
                can_tx( can_channel_ext, DebugV_PDO4_Tx,can_ext_tx.signal.debugv_tx_pdo4.u8data,8);//can_ext_tx_send_v_debug4();
            }
        }
    }

}
static void can_ext_tx_send_msg_1ms(void)
{
    if(kwpservices_get_passive_mode())
    {
        /* send no process data when switched to passive mode */
    }
    else
    {
        if( NTH( &can_ext_tx.delay_cnt_2ms, 1 ))
        {
            PrTrmExtTracPDOF();
            can_tx( can_channel_ext, V_Trac_PDOF_TX,can_ext_tx.signal.v_trac_tx_pdof.u8data,8 );
        }

        if( NTH( &can_ext_tx.delay_cnt_10ms, 9 ))
        {
            PrTrmExtLiftPDO1(); /*10ms*/
            can_tx( can_channel_ext, SYNC_Tx,       NIL,0); // can_ext_tx_send_sync();
            can_tx( can_channel_ext, V_Lift_PDO1_TX,can_ext_tx.signal.v_lift_tx_pdo1.u8data,8);//can_ext_tx_send_lift_pdo1();
        }

        if( NTH(&can_ext_tx.delay_cnt_20ms,19))
        {
            PrTrmExtTracPDO1(); /*20ms*/
            PrTrmExtTracPDO2(); /*20ms*/
            PrTrmExtTracPDO5(); /*20ms*/
            PrTrmExtLiftPDO2(); /*20ms*/
            can_tx( can_channel_ext, V_Trac_PDO1_TX,  can_ext_tx.signal.v_trac_tx_pdo1.u8data,8);// can_ext_tx_send_trac_pdo1();
            can_tx( can_channel_ext, V_Trac_PDO2_TX,  can_ext_tx.signal.v_trac_tx_pdo2.u8data,8);//can_ext_tx_send_trac_pdo2();
            can_tx( can_channel_ext, V_Trac_PDO5_TX,  can_ext_tx.signal.v_trac_tx_pdo5.u8data,8);//can_ext_tx_send_trac_pdo5();
            can_tx( can_channel_ext, V_Lift_PDO2_TX,  can_ext_tx.signal.v_lift_tx_pdo2.u8data,8);//can_ext_tx_send_lift_pdo2();
        }

        if( NTH( &can_ext_tx.delay_cnt_40ms, 39 ))
        {
            U8 heartbeat_state = 0x05;
            can_tx( can_channel_ext, V_Trac_Heartbeat, &heartbeat_state,1);  //can_ext_tx_heartbeat();
            
        }

    }

}

static void PrTrmExtLiftPDO1(void)
{
    U8 static MsgCnt;
    L_SpeedSet_s16 = output_data.pump_motor_rpm;
    L2_dm2_b1 = 0;
    L2_dm3_b1 = 0;
    L2_dm4_b1 = 0;
    L2_dm5_b1 = 0;
    L2_dm6_b1 = 0;
    L2_dm7_b1 = 0;
    L2_dm8_b1 = 0;
    L2_dm9_u8 = 0;
	
    L_CMain_b1      = output_data.main_contactor_flag;
    L_Enable_b2     = output_data.L_Enable;
    L_MessCount_b4  = (++MsgCnt) & 0x0f;
    L_MTemp_s8      = input_data.temperature_motor_2 + 40 ;
    L_PwmEnable_b1  = output_data.pwmEnabl;
    L_TorqueSet_s16 = output_data.pump_motor_torque;
    L_Discharge_b1  = output_data.pump_motor_discharge;
}

static void PrTrmExtLiftPDO2(void)
{
    /*send to display*/
    U8 static MsgCnt;
	
    IndHeight_b1         = (output_data.fH13 || output_data.H13_ae);  
    LiftActive_b1        = (output_data.ChAbsMax >VSET_NEUTRAL);    
    LiftCtrlErrState_b1  = output_data.fH1R;
    LiftH3Cmd_b1         = (DTCcnt || output_data.fH3Y);
    LiftH5Cmd_b1         = output_data.fH5Rl;  
    LiftH7Cmd_b1         = (output_data.H7YP );  
    LiftH8Cmd_b1         = (output_data.fH8Yl);
    LiftHeight_b15       = U16_CONST(32767);  
    LiftMastPos_b1       = (output_data.AngPositionSA == 1);  
    LiftTiltAng_s8       = S8_CONST(127);  
    LiftWarnBuzzCmd_b1   = output_data.buzzer; 
	LiftH11Cmd_b1        = output_data.H11R;  
	Lift2MsgCnt_b2       = (++MsgCnt)&0xF;  

	LloState_b2          = 0;  
    TapDir_b2            = 0;  
    TapState_b2          = 0;  
	WeightProc_b1        = 0;
    ChlState_b1          = 0;  
    L1_MotorTemp_s8      = 0;  /*reserved*/  
	Lh2State_b1          = 0;  
    LhpDir_b2            = 0;  
    LhpState_b2          = 0;  
	LiftFuncBuzzCmd_b1   = 0;  /*activate display function buzzer*/
    LiftH14Cmd_b1        = 0;  /*H14 red  assist lamp*/
    LiftH17Cmd_b1        = 0;  /*H17 yellow  assist lamp*/
    LiftLoadState_b1     = 0;  
    LiftSymbACmd_b1      = 0;  
}

static void PrTrmExtTracPDOF(void)
{
    T_TorqueSetF_lft_s16  = (S16)(output_data.mL_mSet_To_LAC / can_resol_torque );
    T_EnableF_Lft_b2      = output_data.mL_CmdEnable;
    T_PwmEnableF_lft_b1   = output_data.mL_CmdPwmEna_1;
    T_Discharge_lft_b1    = output_data.mL_discharge;
    
    T_TorqueSetF_rgh_s16  = (S16)(output_data.mR_mSet_To_LAC / can_resol_torque );
    T_EnableF_Rgh_b2      = output_data.mR_CmdEnable;
    T_PwmEnableF_rgh_b1   = output_data.mR_CmdPwmEna;
    T_Discharge_rgh_b1    = output_data.mR_discharge;
    
    T_MessCountF_b4       = (output_data.mLR_CmdHBeatCnt++) & 0x0f;   

    TF_dm2_b1             = 0;   
    TF_dm3_b1             = 0;   
    TF_dm4_b1             = 0;   
    TF_dm5_b1             = 0;   
    TF_dm7_u8             = 0;   
    TF_dm8_u8             = 0;   
}

static void PrTrmExtTracPDO1(void)
{
    S16 canTrSpeed1;
    //S16 canTruckSpeed;
    S16 canTSteerAngle;
    
    canTrSpeed1    = (S16)(output_data.ou_tr_vSen / 0.001f);
    canTSteerAngle = output_data.fDiff ? 0x7FFF : middle_s16(-900, input_data.te_Angle * PI / (2.0f * middle_f32(0.1f, st_amplit, 2.0f)), 900);

    /*send to display*/
    TrSpeed_s16         = canTrSpeed1; /* mm/s */
    Truck_ForceN_s16    = 0;                
    TruckSpeed_s16      = ABS(output_data.te_vSen * 1000.0f);   /* Km/h */
    TSteerAngle_s16     = canTSteerAngle;   
    
}
static void PrTrmExtTracPDO2(void)
{
    /*send to display*/
    BatCharState_u8       = (U8)(output_data.ba_qbat_Disp);     /* battery charge ratio (bdi)   display*/;   
    BrakeState_b1         = output_data.ou_park_break_switch;  //  || (output_data.ou_fBlinkBrk && output_data.ou_bBlink1_0Hz);  /* continuous: hand brake activated, blinker: seat switch logic in deceleration mode */;
    HourmeterCmd_b1       = output_data.ou_bHourMeter;          /*work hour  meter*/
    IndBackw_b1           = (output_data.ou_direction == direction_switch_state_reverse);  
    IndForw_b1            = (output_data.ou_direction == direction_switch_state_forward);  
    T_BatCurr_u16         = 0;  

	T_BatVolt_u16         = output_data.Bat_voltage*100.0f;
    T_MotTemp_lft_u8      = output_data.trac_temperature + 40;  
    T_Seat_b1             = output_data.ou_seat_switch_1;                             /* seat switch   LTI: F07 */ 
    T_TotalDischarge_b1   = 1;//output_data.ou_fDeepDis;                                  /* deep discharge    */
    TracActive_b1         = output_data.tr_bActive;                                   /* general flag indication traction activity */    
    TracCtrlErrState_b1   = output_data.ou_fLampErr;                                  /* error lamp */  
    TracH11Cmd_b1         = 0;  
    TracH3Cmd_b1          = (!!DTCcnt) || output_data.ou_fLampBook;                   /* H3 on if DTC present or demanded by application */;  
    TracH5Cmd_b1          = output_data.ou_fLampRed;                                  /* motor overtemp  red*/
    TracH7Cmd_b1          = output_data.ou_fLampH7 || (output_data.ou_fBlinkH7 && output_data.ou_bBlink1_0Hz);  /* H7  neutral yellow signal*/; 
    TracH8Cmd_b1          = output_data.ou_fLampYel;                                             /* motor overtemp  yellow*/
    TracH9Cmd_b1          = output_data.ou_fRedu1 || output_data.ou_fRedu2 || output_data.fLampH9;              /* speed reduction switch */;  
    TracSymbACmd_b1       = !(output_data.ou_seat_switch_1)  || (output_data.ou_fBlinkSA && output_data.ou_bBlink1_0Hz); /* Symbol A                                        */;
    TracWarnBuzzCmd_b1    = (!!DTCcnt) || output_data.buzzer;                         /* Buzzer;  */
}
static void PrTrmExtTracPDO3(void)
{
    Vehicle_DTC1_u16    = output_data.vehicle_dtc[0];    
    Vehicle_DTC2_u16    = output_data.vehicle_dtc[1];    
    Vehicle_DTC3_u16    = output_data.vehicle_dtc[2];    
    Vehicle_DTC4_u16    = output_data.vehicle_dtc[3];    

}
static void PrTrmExtTracPDO4(void)
{
    TruckWorkTime_u32 = timerecoder_get(timerecoder_channel_component_work_time);/*units seconds*/
}

static void PrTrmExtTracPDO5(void)
{
    U8  static MsgCnt;
    U16 canRWT;

    canRWT = (U16)middle_f32(0.0f, output_data.ba_dT_BatFlat_min, 599.0f);  /* remaining work time (bdi) limited to 10h - 1min = 599min */

    /*send to display*/
    PbBrake_b1           = 0;                   /*unused signal (reserved for LFI)*/ 
    PermHeight_u16       = 0;   
    PermTiltAngB_u8      = 0;   
    PermTiltAngF_u8      = 0;   
    RemWorkTime_b11      = canRWT;   
    RWT_Ovfl_b1_b1       = (output_data.ba_dT_BatFlat_min > 599.0f ? 1 : 0) ;    /*  remaining work time (bdi) exceeds limit*/
    SpLimState_b1        = 0;   
    TLift_b1             = 0;   
    Trac5MsgCnt_b4       = (++MsgCnt) & 0xF;   
    TracDirLev_b2        = (input_data.direction);   
    TracFuncBuzzCmd_b1   = 0;   
    TracH14Cmd_b1        = 0;   
    TracH15Cmd_b1        = 0;   
    TracH16Cmd_b1        = output_data.fH16;   /* H16 boot lid contact open */  
    TracH17Cmd_b1        = 0;   
    TracH2Cmd_b1         = 0;   
    TracH4Cmd_b1         = 0;   
    TracInterv_b2        = 0;   
    TrBrk_b1             = !(input_data.park_break_switch);   
}

static void PrTrmExtDebugPDO0(void)
{
    Vechicle_debug0_0_u16 = output_data.v_debug_0[0];
    Vechicle_debug0_1_u16 = output_data.v_debug_0[1];
    Vechicle_debug0_2_u16 = output_data.v_debug_0[2];
    Vechicle_debug0_3_u16 = output_data.v_debug_0[3]; 
}

static void PrTrmExtDebugPDO1(void)
{
    Vechicle_debug1_0_u16 = output_data.v_debug_1[0];
    Vechicle_debug1_1_u16 = output_data.v_debug_1[1];
    Vechicle_debug1_2_u16 = output_data.v_debug_1[2];
    Vechicle_debug1_3_u16 = output_data.v_debug_1[3];    
}

static void PrTrmExtDebugPDO2(void)
{
    Vechicle_debug2_0_u16 = output_data.v_debug_2[0];
    Vechicle_debug2_1_u16 = output_data.v_debug_2[1];
    Vechicle_debug2_2_u16 = output_data.v_debug_2[2];
    Vechicle_debug2_3_u16 = output_data.v_debug_2[3]; 
}
static void PrTrmExtDebugPDO3(void)
{
    Vechicle_debug3_0_u16 = output_data.v_debug_3[0];
    Vechicle_debug3_1_u16 = output_data.v_debug_3[1];
    Vechicle_debug3_2_u16 = output_data.v_debug_3[2];
    Vechicle_debug3_3_u16 = output_data.v_debug_3[3];
}
static void PrTrmExtDebugPDO4(void)
{
    Vechicle_debug4_0_u16 = output_data.v_debug_4[0];
    Vechicle_debug4_1_u16 = output_data.v_debug_4[1];
    Vechicle_debug4_2_u16 = output_data.v_debug_4[2];
    Vechicle_debug4_3_u16 = output_data.v_debug_4[3]; 
}


/***********************************************************************************************************************
 *                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
 ***********************************************************************************************************************/
